using System;
using System.Collections.Generic;
using FireStarter.Base;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using Habanero.Base;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.BO.Loaders;

namespace FireStarterModeller.Test.Logic
{
    public static class TestUtilsLogic
    {
        internal static void WaitForGC()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        internal static void SetupTest()
        {
            BORegistry.DataAccessor = new DataAccessorInMemory();
            BusinessObjectManager.Instance.ClearLoadedObjects();
            WaitForGC();
        }

        internal static void SetupFixture()
        {
            ClassDef.ClassDefs.Clear();
            ClassDef.ClassDefs.Add(new XmlClassDefsLoader(BOBroker.GetClassDefsXml(), new DtdLoader()).LoadClassDefs());
        }

        public static DMClass CreateClassWithStringPropertyAsPK()
        {
            DMSolution solution = TestUtilsShared.CreateSavedDMSolution();
            DMAssembly assembly = solution.DefaultAssembly;
            return CreateClassWithStringProperty(assembly);
        }

        public static DMClass CreateClassWithOneGuidProperty()
        {
            DMSolution solution = TestUtilsShared.CreateSavedDMSolution();
            DMAssembly assembly = solution.DefaultAssembly;
            return CreateClassWithOneGuidProperty(assembly);
        }

        internal static DMClass CreateClassWithStringProperty(DMAssembly assembly)
        {
            DMClass dmClass = assembly.CreateClass(TestUtilsShared.GetRandomString());
            TestUtilsShared.UpdateBusinessObjectWithValidData(dmClass);
            //DMClass dmClass = TestUtilsShared.CreateSavedDMClass();
            DMPropertyType propertyType = GetStringPropertyType();

            if (dmClass.ObjectIdentity == null)
            {
                DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
                dmProperty.PropertyType = propertyType;
                //dmProperty.DefaultPropRule = null;
                dmClass.Properties.Add(dmProperty);
                dmClass.ObjectIdentity = new DMObjectIdentity();
                dmClass.ObjectIdentity.Properties.Add(dmProperty);
            }
            else
            {
                DMProperty property = dmClass.Properties[0];
                property.PropertyType = propertyType;
            }
            return dmClass;
        }

        internal static DMClass CreateClassWithOneGuidProperty(DMAssembly assembly)
        {
            DMClass dmClass = TestUtilsShared.CreateSavedDMClass(assembly);
            DMPropertyType propertyType = GetGuidPropertyType();
            if (dmClass.ObjectIdentity == null)
            {
                DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty();
                dmProperty.PropertyType = propertyType;
                dmProperty.DefaultPropRule = null;
                dmClass.Properties.Add(dmProperty);


                dmClass.ObjectIdentity = new DMObjectIdentity();
                dmClass.ObjectIdentity.Properties.Add(dmProperty);
            }
            else
            {
                DMProperty property = dmClass.Properties[0];
                property.PropertyType = propertyType;
                property.DefaultPropRule = null;
            }
            return dmClass;
        }

        internal static DMClass CreateClassTwoProperties()
        {
            DMClass dmClass = CreateClassWithOneGuidProperty();
            AddPropertyWithNoRules(dmClass);
            return dmClass;
        }

        private static DMPropertyType _guidPropertyType;
        private static DMPropertyType _intPropertyType;
        private static DMPropertyType _stringPropertyType;

        internal static DMPropertyType GetGuidPropertyType()
        {
            if (_guidPropertyType == null) _guidPropertyType = CreatePropertyType("System", "Guid");
            return _guidPropertyType;
        }

        internal static DMPropertyType GetIntegerPropertyType()
        {
            if (_intPropertyType == null) _intPropertyType = CreatePropertyType("System", "Int32");
            return _intPropertyType;
        }

        internal static DMPropertyType GetStringPropertyType()
        {
            if (_stringPropertyType == null) _stringPropertyType = CreatePropertyType("System", "String");
            return _stringPropertyType;
        }

        private static DMPropertyType CreatePropertyType(string assemblyName, string propertyTypeName)
        {
            DMPropertyType propertyType = new DMPropertyType
                                              {AssemblyName = assemblyName, PropertyTypeName = propertyTypeName};
            return propertyType;
        }

        internal static DMProperty AddPropertyWithNoRules(DMClass dmClass)
        {
            DMProperty property = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            property.PropertyType = GetIntegerPropertyType();
            return property;
        }

        internal static DMProperty AddGuidProperty(DMClass dmClass)
        {
            DMProperty property = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            property.PropertyType = GetGuidPropertyType();
            return property;
        }

        public static DMClass CreateClassWithOneUIView()
        {
            DMClass dmClass = CreateClassWithNoUIViews();
            UIView view = dmClass.UIViews.CreateBusinessObject();
            string viewName = TestUtilsShared.GetRandomString();
            view.ViewName = viewName;
            PopulateViewFormAndGrid(dmClass, view);
            return dmClass;
        }

        public static void PopulateViewFormAndGrid(DMClass dmClass, UIView view)
        {
            UIFormCreator uiFormCreator = new UIFormCreator();
            UIFormInfo formInfo = uiFormCreator.CreateUIForm(dmClass);
            view.UIFormInfo = formInfo;
            UIGridCreator uiGridCreator = new UIGridCreator();
            UIGridInfo gridInfo = uiGridCreator.CreateGrid(dmClass, dmClass.Properties);
            view.UIGridInfo = gridInfo;
        }

        public static DMClass CreateClassWithTwoUIViews()
        {
            DMClass dmClass = CreateClassWithNoUIViews();
            UIView view = dmClass.UIViews.CreateBusinessObject();
            view.ViewName = TestUtilsShared.GetRandomString();
            PopulateViewFormAndGrid(dmClass, view); 
            UIView view2 = dmClass.UIViews.CreateBusinessObject();
            view2.ViewName = TestUtilsShared.GetRandomString();
            PopulateViewFormAndGrid(dmClass, view);
            return dmClass;
        }

        public static DMClass CreateClassWithNoUIViews()
        {
            return CreateClassWithOneGuidProperty();
        }
    }

    public class EntityStub : BusinessObject
    {
        public EntityStub(IClassDef def)
            : base(def)
        {
        }

        public EntityStub()
        {
        }
    }

    public class PropRuleStub : PropRuleBase
    {
        public PropRuleStub(string name, string message)
            : base(name, message)
        {
            _parameters["Param1"] = "";
        }

        protected override void SetupParameters()
        {
        }

        public override List<string> AvailableParameters
        {
            get
            {
                {
                    return new List<string> { "Param1" };
                }
            }
        }
    }
}